<?php

namespace Modules\H5\Http\Controllers\Order;

use Modules\Common\Models\Ebooks;
use Modules\Common\Models\Members;
use Modules\Common\Models\Orders;
use Modules\Common\Models\SubscriptionTypes;
use Modules\Common\Models\Coupons;
use Modules\Common\Util\Api;
use Modules\Common\Util\Database;
use Carbon\Carbon;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class Order
{
    
    /**
     *获取订阅类型
     * @Route(path=/api/h5/subscription-type)
     */
    public function subscriptionType()
    {
        $eid = auth('web')->user()->eid;
        $subscriptionTypes = SubscriptionTypes::where('status',1)->where('eid',$eid)->get();
        return Api::success($subscriptionTypes);
    }
    
    /**
     * 创建购买电子书订单
     * @Route(path=/api/h5/buy-ebook method=post)
     */
    public function buyEbook()
    {
        $key = config('encryption.key');
        $iv = config('encryption.iv');
        $bookId = request('book_id'); // 电子书
        $paymentMethod = request('payment_method'); // 支付方式
        $channel = 'read'; // 订单来源
    
        // 检查电子书是否存在
        $ebook = Ebooks::find($bookId);
        if (!$ebook) {
            return Api::fail('电子书不存在', 404);
        }
        // 创建支付订单
        $orderSn = $this->generateOrderSn(); // 生成订单编号
        $order = new Orders();
        //检查订单编号是否已存在
        if ($order->where('order_sn', $orderSn)->exists()) {
            // 如果存在，重新生成
            return $this->generateOrderSn();
        }
        $userId = auth('web')->user()->id;
        $sid = $ebook->sid;//通过电子书获取集团id
        $eid = auth('web')->user()->eid;
        
        $points = 0; // 积分数
        $noticeUrl = config('encryption.back_api_url').'/api/payment-callback'; //通知接口的地址
        $secretKey = $this->encrypt($orderSn,$key,$iv); // 加密参数
        $callback =''; //支付成功通知地址
        $payUrl = config('encryption.pay_url')."/?eid=%d&amount=%.2f&points=%d&orderSn=%s&noticeUrl=%s&secretKey=%s&type=transfer&callback=%s";
        $paymentUrl = sprintf($payUrl,$eid, $ebook->price, $points, $orderSn, urlencode($noticeUrl), $secretKey,$callback);
        //主库数据插入
        $order->order_sn = $orderSn;
        $order->ebook_id = $bookId;
        $order->user_id = $userId;
        $order->sid =  $sid;
        $order->eid = $eid;
        $order->status = 1; // 待支付
        $order->payment_method = $paymentMethod;
        $order->total_amount = $ebook->price;
        $order->channel = $channel; // 保存订单来源
        $order->payment_url = $paymentUrl;
        $order->order_date = date('Y-m-d H:i:s');
        $order->created_at = date('Y-m-d H:i:s');
        $order->save();
        //子库数据插入
       DB::connection('platform')->transaction(function () use ($sid,$eid,$channel, $orderSn, $userId,$paymentMethod, $ebook) {
            // 现在你可以在闭包内部访问 $channel, $orderSn, $paymentMethod, 和 $ebook 变量
            DB::connection('platform')->table('pay_order')->insert([
                'sid' => $sid,
                'eid' => $eid,
                'channel' => $channel,
                'desc' => '电子书购买',
                'order_sn' => $orderSn,
                'user_id' => $userId,
                'quantity' => 1,
                'consumed_points' => 0,
                'payment_method' => $paymentMethod,
                'consumed_amount' => $ebook->price,
                'order_status' => 'pending_payment',
                'created_at' => date('Y-m-d H:i:s')
            ]);
        });
    
        
        return Api::success([
            'msg' => '订单创建成功！',
            'order_id' => $order->id,
            'order_sn' => $order->order_sn,
            'payment_url' => $paymentUrl
        ]);
    }
    
    
    /**
     * 一次性购买支付回调处理
     * @Route(path=/api/payment-callback method=post)
     */
    public function paymentCallback()
    {
        $tradeState = request('trade_state');
        $orderSn = request('order_sn');
        $key = config('encryption.key');
        $iv = config('encryption.iv');
        $orderSn = $this->decrypt($orderSn,$key,$iv);
        Log::info('支付回调', [
            'data' => request(),
        ]);
        $order = Orders::where('order_sn', $orderSn)->first();
        if (!$order) {
            return Api::fail('订单记录不存在', 404);
        }
        // SUCCESS：支付成功
        // REFUND：转入退款
        // NOTPAY：未支付
        // CLOSED：已关闭
        // REVOKED：已撤销（付款码支付）
        // USERPAYING：用户支付中（付款码支付）
        // PAYERROR：支付失败(其他原因，如银行返回失败)
        // 更新订单状态
        if ($tradeState == 'SUCCESS') {
            $order->status = 2; // 支付成功状态码
            $orderStatus = "completed";
        } elseif ($tradeState == 'REFUND' || $tradeState == 'CLOSED' || $tradeState == 'REVOKED' || $tradeState == 'PAYERROR' || $tradeState == 'USERPAYING') {
            $order->status = 3; // 支付取消状态码
             $orderStatus = "cancelled";
        }elseif ($tradeState == 'NOTPAY') {
            $order->status = 1; // 待支付状态码
            $orderStatus = "pending_payment";
        }
        $order->updated_at = date('Y-m-d H:i:s'); // 更新订单完成时间
    
        $order->save();
        
        DB::connection('platform')->transaction(function () use ($orderSn,$orderStatus) {
            // 更新数据
            DB::connection('platform')->table('pay_order')
                ->where('order_sn', $orderSn)
                ->update([
                    'order_status' => $orderStatus,
                    'updated_at' => date('Y-m-d H:i:s')
                ]);
        });
    
        // 返回成功消息和跳转页面地址
        return Api::success([
            'msg' => '支付状态更新成功！',
            'order_status' => $order->status,
        ]);
    }
        
    
    /**
     * 创建购买会员订单
     * @Route(path=/api/h5/buy-member method=post)
     */
    public function buyMember()
    {
        $key = config('encryption.key');
        $iv = config('encryption.iv');
        $userId = auth('web')->user()->id;
        $subscriptionTypeId = request('subscription_type_id');
        $paymentMethod = request('payment_method');
        $couponCode = request('coupon_code');
        $channel = 'read'; // 订单来源
    
        // 检查订阅类型是否存在
        $subscriptionType = SubscriptionTypes::find($subscriptionTypeId);
        if (!$subscriptionType) {
            return Api::fail('订阅类型不存在', 404);
        }
    
        // 计算会员费用，考虑优惠券折扣
        $membershipFee = $this->calculateMembershipFee($subscriptionType, $couponCode);
    
        // 创建支付订单
        $orderSn = $this->generateOrderSn();
        $order = new Orders();
        // 检查订单编号是否已存在
        if ($order->where('order_sn', $orderSn)->exists()) {
            // 如果存在，重新生成
            return $this->generateOrderSn();
        }
        $sid =  $subscriptionType->sid;//通过订阅类型获取集团sid;
        $eid = auth('web')->user()->eid;
        
         // 生成支付跳转链接
        $points = 0; // 积分数
        $noticeUrl = config('encryption.back_api_url').'/api/payment-memner-callback'; //通知接口的地址
        $secretKey = $this->encrypt($orderSn,$key,$iv); // 加密参数
        $callback =''; //支付成功通知地址
        $payUrl = config('encryption.pay_url')."/?eid=%d&amount=%.2f&points=%d&orderSn=%s&noticeUrl=%s&secretKey=%s&type=transfer&callback=%s";
        $paymentUrl = sprintf($payUrl,$eid, $membershipFee, $points, $orderSn, urlencode($noticeUrl), $secretKey,$callback);
        //主库数据插入
        $order->order_sn = $orderSn;
        $order->user_id = $userId;
        $order->sid =  $sid;
        $order->eid = $eid;
        $order->status = 1;
        $order->payment_method = $paymentMethod;
        $order->total_amount = $membershipFee;
        $order->channel = $channel;
        $order->payment_url = $paymentUrl;
        $order->order_date = date('Y-m-d H:i:s');
        $order->created_at = date('Y-m-d H:i:s');
        $order->subscription_type_id = $subscriptionTypeId;
        $order->save();
        
         //子库数据插入
        DB::connection('platform')->transaction(function () use ($userId,$sid,$eid,$channel, $orderSn, $paymentMethod, $membershipFee){
            DB::connection('platform')->table('pay_order')->insert([
                'user_id'=>$userId,
                'sid'=> $sid,
                'eid'=>$eid,
                'channel'=>$channel,
                'desc'=>'会员购买',
                'order_sn'=>$orderSn,
                'quantity'=>1,
                'consumed_points'=> 0,
                'payment_method'=>$paymentMethod,
                'consumed_amount'=>$membershipFee,
                'order_status'=>'pending_payment',
                'created_at'=>date('Y-m-d H:i:s')
            ]);
        });
    
       
    
        return Api::success([
            'msg' => '会员购买成功！',
            'order_id' => $order->id,
            'order_sn' => $order->order_sn,
            'payment_url' => $paymentUrl
        ]);
    }
    
    /**
     * 计算会员费用，考虑优惠券
     */
    protected function calculateMembershipFee($subscriptionType, $couponCode)
    {
        // 这里可以添加优惠券逻辑
        return $subscriptionType->price;
    }
    
    /**
     * 会员支付回调处理
     * @Route(path=/api/payment-memner-callback method=post)
     */
    public function paymentMemberCallback()
    {
        $tradeState = request('trade_state');
        $orderSn = request('order_sn');
        $key = config('encryption.key');
        $iv = config('encryption.iv');
        $orderSn = $this->decrypt($orderSn,$key,$iv);
        Log::info('支付回调', [
            'data' => request(),
        ]);

        $order = Orders::where('order_sn', $orderSn)->first();
        if (!$order) {
            return Api::fail('订单记录不存在', 404);
        }
    
        $userId = $order->user_id;
        $subscriptionTypeId = $order->subscription_type_id;
        $subscriptionType = SubscriptionTypes::find($subscriptionTypeId);
        $paymentMethod = $order->payment_method;
        $membershipFee = $order->total_amount;
    
        // 更新子库订单状态
        if ($tradeState == 'SUCCESS') {
            $order->status = 2;
            $orderStatus = 'completed';
            // 检查是否已经存在会员记录
            $member = Members::where('user_id', $userId)->first();
            
            if($member) {
                // 确保 end_date 是 Carbon 实例
                $currentEndDate = Carbon::parse($member->end_date);
                
                // 如果会员记录存在且还未到期，更新到期日期
                if ($currentEndDate->gt(Carbon::now())) {
                // 如果会员记录存在且还未到期，检查是否续费为永久会员
                    if ($subscriptionType->duration == -1) {
                        // 续费为永久会员
                        $member->end_date = Carbon::createFromFormat('Y-m-d', '9999-12-31')->startOfDay();
                    } else {
                        // 续费为常规会员，延长现有会员期限
                        $new_end_date = Carbon::createFromFormat('Y-m-d H:i:s', $member->end_date);
                        $member->end_date =$new_end_date->addDays($subscriptionType->duration);
                    }
                } else {
                    // 如果会员已经到期，或者这是第一次续费，根据新的订阅类型设置结束日期
                    $member->end_date = now()->addDays($subscriptionType->duration == -1 ? '9999-12-31' : $subscriptionType->duration);
                }
                
                // 更新其他会员信息
                $member->level_id = $subscriptionType->id;
                $member->status = 1;
                $member->payment_method = $paymentMethod;
                $member->subscription_type_id = $subscriptionType->id;
                $member->membership_fee = $membershipFee;
                $member->auto_renew = request('auto_renew', '2');
                $member->start_date = now();
                $member->eid = $subscriptionType->eid;
                $member->sid = $subscriptionType->sid;
                $member->save();
            } else {
                // 如果不存在，创建新的会员记录
                $member = new Members();
                $member->user_id = $userId;
                $member->level_id = $subscriptionType->id;
                $member->start_date = now();
                if ($subscriptionType->duration == -1) {
                    $member->end_date = Carbon::createFromFormat('Y-m-d', '9999-12-31')->startOfDay();
                } else {
                    $member->end_date = now()->addDays($subscriptionType->duration);
                }
                $member->status = 1;
                $member->payment_method = $paymentMethod;
                $member->subscription_type_id = $subscriptionType->id;
                $member->membership_fee = $membershipFee;
                $member->auto_renew = request('auto_renew', '2');
                $member->eid = $subscriptionType->eid;
                $member->sid = $subscriptionType->sid;
                $member->save();
            }
        
            // 更新会员id
            $order->member_id = $member->id;
            $order->start_date = $member->start_date;
            $order->end_date = $member->end_date;
        } elseif ($tradeState == 'REFUND' || $tradeState == 'CLOSED' || $tradeState == 'REVOKED' || $tradeState == 'PAYERROR' || $tradeState == 'USERPAYING') {
            $order->status = 3;
            $orderStatus = 'cancelled';
        }elseif($tradeState == 'NOTPAY'){
            $order->status = 1;
            $orderStatus = 'pending_payment';
        }

        $order->updated_at = date('Y-m-d H:i:s'); // 更新订单完成时间
         //单独记录一下会员的订阅开始时间和结束时间
        $order->save();

        //更新子库记录
        DB::connection('platform')->transaction(function () use ($orderSn,$orderStatus) {
            // 更新数据
            DB::connection('platform')->table('pay_order')
                ->where('order_sn', $orderSn)
                ->update([
                    'order_status' => $orderStatus,
                    'updated_at' => date('Y-m-d H:i:s')
                ]);
        });
    
        return Api::success([
            'msg' => '支付状态更新成功！',
            'order_status' => $order->status,
        ]);
    }
    
    
    /**
     * 订单轮询处理
     * @Route(path=/api/h5/poll-order-status)
     */
    public function pollOrderStatus()
    {
        $orderSn = request('order_sn');
        // 检查订单是否存在
        $order = Orders::where('order_sn', $orderSn)->first();

        if (!$order) {
            return Api::fail('订单记录不存在', 404);
        }

        // 检查订单状态
        if ($order->status === 2) {
             return Api::success([
                'msg' => '订单已完成！',
                'order_status' => $order->status,
            ]);
        } elseif ($order->status === 3) {
             return Api::fail('订单失败！',['order_status' => $order->status]);
        }

        // 如果订单状态不是完成或失败fail，返回等待中
        return Api::success([
            'msg' => '订单处理中！',
            'order_status' => $order->status,
        ]);
    }
    
    /**
     * 查询订单状态
     * @Route(path=/api/check-wechat-order-status)
     */
    public function checkWechatOrderStatus()
    {
        $orderSn = request('order_sn');
        // 检查订单号是否提供
        if (!$orderSn) {
            return Api::fail('订单号不能为空', 400);
        }
    
        // 检查订单是否存在
        $order = Orders::where('order_sn', $orderSn)->first();
        
        if (!$order) {
            return Api::fail('订单记录不存在', 404);
        }
        // 根据订单号去找会员
        $userId = $order->user_id;
        $subscriptionTypeId = $order->subscription_type_id;
        $subscriptionType = SubscriptionTypes::find($subscriptionTypeId);
        $paymentMethod = $order->payment_method;
        $membershipFee = $order->total_amount;
        // 调用提供的接口或查询数据库获取订单状态
        try {
            $wechatOrderStatus = $this->getWechatOrderStatus($orderSn);
            if ($wechatOrderStatus['code'] === 0 && isset($wechatOrderStatus['data']['status']) && $wechatOrderStatus['data']['status'] === "SUCCESS") {
                // 检查是否已经存在会员记录
                $member = Members::where('user_id', $userId)->first();
                if($member) {
                     // 确保 end_date 是 Carbon 实例
                    $currentEndDate = Carbon::parse($member->end_date);
                    // 如果会员记录存在且还未到期，更新到期日期
                    if ($currentEndDate->gt(Carbon::now())) {
                    // 如果会员记录存在且还未到期，检查是否续费为永久会员
                        if ($subscriptionType->duration == -1) {
                            // 续费为永久会员
                            $member->end_date = Carbon::createFromFormat('Y-m-d', '9999-12-31')->startOfDay();
                        } else {
                            // 续费为常规会员，延长现有会员期限
                            $new_end_date = Carbon::createFromFormat('Y-m-d H:i:s', $member->end_date);
                            $member->end_date =$new_end_date->addDays($subscriptionType->duration);
                            
                        }
                    } else {
                        // 如果会员已经到期，或者这是第一次续费，根据新的订阅类型设置结束日期
                        $member->end_date = now()->addDays($subscriptionType->duration == -1 ? '9999-12-31' : $subscriptionType->duration);
                    }
                    
                    // 更新其他会员信息
                    $member->level_id = $subscriptionType->id;
                    $member->status = 1;
                    $member->payment_method = $paymentMethod;
                    $member->subscription_type_id = $subscriptionType->id;
                    $member->membership_fee = $membershipFee;
                    $member->auto_renew = request('auto_renew', '2');
                    $member->start_date = now();
                    $member->eid = $subscriptionType->eid;
                    $member->sid = $subscriptionType->sid;
                    $member->save();
                } else {
                    // 如果不存在，创建新的会员记录
                    $member = new Members();
                    $member->user_id = $userId;
                    $member->level_id = $subscriptionType->id;
                    $member->start_date = now();
                    if ($subscriptionType->duration == -1) {
                        $member->end_date = Carbon::createFromFormat('Y-m-d', '9999-12-31')->startOfDay();
                    } else {
                        $member->end_date = now()->addDays($subscriptionType->duration);
                    }
                    $member->status = 1;
                    $member->payment_method = $paymentMethod;
                    $member->subscription_type_id = $subscriptionType->id;
                    $member->membership_fee = $membershipFee;
                    $member->auto_renew = request('auto_renew', '2');
                    $member->eid = $subscriptionType->eid;
                    $member->sid = $subscriptionType->sid;
                    $member->save();
                }
                // 更新会员id
                $order->updated_at = date('Y-m-d H:i:s'); // 更新订单完成时间
                $order->member_id = $member->id;
                $order->status = 2; // 2表示订单成功
                //单独记录一下会员的订阅开始时间和结束时间
                $order->start_date = $member->start_date;
                $order->end_date = $member->end_date;
                Log::info('支付回调', [
                    'start_date' => $order->start_date,
                    'end_date' => $order->end_date,
                ]);
                $order->save();
                $orderStatus = 'completed';
                //更新子库记录
                DB::connection('platform')->transaction(function () use ($orderSn,$orderStatus) {
                    // 更新数据
                    DB::connection('platform')->table('pay_order')
                        ->where('order_sn', $orderSn)
                        ->update([
                            'order_status' => $orderStatus,
                            'updated_at' => date('Y-m-d H:i:s')
                        ]);
                });
                return Api::success([
                    'msg' => '订单状态已更新',
                    'order_status' => $order->status,
                ]);
            } else {
                $order->status = 3; // 3表示订单失败
                $order->save();
                $orderStatus = 'cancelled';
                 //更新子库记录
                DB::connection('platform')->transaction(function () use ($orderSn,$orderStatus) {
                    // 更新数据
                    DB::connection('platform')->table('pay_order')
                        ->where('order_sn', $orderSn)
                        ->update([
                            'order_status' => $orderStatus,
                            'updated_at' => date('Y-m-d H:i:s')
                        ]);
                });
                return Api::fail('支付失败，订单失败！', 400, ['order_status' => $order->status]);
            }
        } catch (\Exception $e) {
            // 处理异常，例如网络请求失败或接口返回错误
            return Api::fail('查询支付状态失败', 500, ['error' => $e->getMessage()]);
        }
    
        // 如果订单状态不是完成或失败，返回等待中
        return Api::success([
            'msg' => '订单处理中，正在等待支付结果！',
            'order_status' => $order->status,
        ]);
    }
    
    /**
     * 调用的API来获取订单状态
     */
    protected function getWechatOrderStatus($orderSn)
    {
        // 使用 GuzzleHttp\Client 发起 GET 请求
        $client = new Client();
        $payResultUrl = config('encryption.pay_result_url').'/api/pay/syncOrder';
        $response = $client->request('GET',$payResultUrl, [
            'query' => [
                'orderSn' => $orderSn
            ]
        ]);
    
        $data = json_decode($response->getBody(), true);
        // 检查响应是否成功
        if (isset($data['code']) && $data['code'] === 0) {
            return $data;
        } else {
            // 如果响应码不是0，抛出异常
            throw new \Exception('支付状态同步失败');
        }
    }


    /**
     * 生成订单编号
     * @return string 返回生成的订单编号
     */
    public function generateOrderSn()
    {
        $prefix = 'R'; // 订单前缀
        $timestamp = time(); // 当前时间戳
        $randomNumber = rand(1000, 9999); // 生成一个随机数
        return $prefix . date('YmdHis', $timestamp) . $randomNumber;
    }
    
     public static function encrypt($data, $key, $iv)
    {
        return base64_encode(openssl_encrypt($data, 'AES-128-CBC', $key, 1, $iv));
    }
    public static function decrypt($data, $key, $iv)
    {
        return openssl_decrypt(base64_decode($data), 'AES-128-CBC', $key, 1, $iv);
    }

}